package org.example.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.rag.content.Content;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.rag.content.retriever.WebSearchContentRetriever;
import dev.langchain4j.rag.query.Query;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.redis.RedisEmbeddingStore;
import dev.langchain4j.store.memory.chat.redis.RedisChatMemoryStore;
import dev.langchain4j.web.search.WebSearchEngine;
import dev.langchain4j.web.search.tavily.TavilyWebSearchEngine;
import okio.Path;
import org.example.domain.vo.InterviewRequest;
import org.example.domain.vo.QuestionResult;
import org.example.domain.vo.SearchAnswerRequest;
import org.example.domain.vo.TransitionResult;
import org.example.mapper.ErrorSetMapper;
import org.example.mapper.KnowledgeLevelMapper;
import org.example.mapper.TopicAboutCompanyMapper;
import org.example.pojo.entity.ErrorSet;
import org.example.pojo.entity.KnowledgeLevel;
import org.example.pojo.entity.TopicAboutCompany;
import org.example.pojo.entity.User;
import org.example.result.Result;
import org.example.service.Interviewer;
import org.example.service.InterviewAccordingToCompanyService;
import org.example.util.CreateModel;

import org.example.util.PdfToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;

@Service
public class InterviewAccordingToCompanyImpl extends ServiceImpl<TopicAboutCompanyMapper, TopicAboutCompany> implements InterviewAccordingToCompanyService {

    @Autowired
    private CreateModel createModel;

    @Autowired
    private TopicAboutCompanyMapper topicAboutCompanyMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ErrorSetMapper errorSetMapper;

    @Autowired
    private KnowledgeLevelMapper knowledgeLevelMapper;

    @Autowired
    private PdfToString pdfToString;

    // 权重配置常量
    private static final double BASE_SEMANTIC_WEIGHT = 0.35;
    private static final double BASE_KEYWORD_WEIGHT = 0.3;
    private static final double BASE_COMPLETENESS_WEIGHT = 0.25;
    private static final double BASE_STRUCTURE_WEIGHT = 0.1;

    // 评分阈值配置
    private static final double HIGH_SIMILARITY_THRESHOLD = 0.8;
    private static final double MEDIUM_SIMILARITY_THRESHOLD = 0.6;
    private static final double LOW_SIMILARITY_THRESHOLD = 0.4;

    // 动态权重调整因子
    private static final double LENGTH_WEIGHT_FACTOR = 0.1;
    private static final double COMPLEXITY_WEIGHT_FACTOR = 0.15;

    // 调整关键词覆盖度阈值
    private static final double KEYWORD_HIGH_THRESHOLD = 0.9; // 原0.7
    private static final double KEYWORD_MEDIUM_THRESHOLD = 0.75; // 原0.5

    // 新增面试流程控制字段
    private int currentTopicIndex = 0;
    private List<String> interviewTopics;
    private int retry = 0;
    private int id = 1;
    private int topicNo = 1;

    @Override
    public Result<List<String>> getTopicAboutCompany(String companyName) {
        List<TopicAboutCompany> topicAboutCompanyList = topicAboutCompanyMapper.selectList(new QueryWrapper<TopicAboutCompany>().eq("company_name", companyName));
        List<String> topicList = new ArrayList<>();


        for (TopicAboutCompany topic : topicAboutCompanyList) {
            topicList.add(topic.getTopicContent());
        }

        return Result.success(topicList);
    }

    @Override
    public Result<List<String>> summarizeKeyWordsAccordingToTheTopic(List<String> topic){
        Interviewer interviewer = AiServices.create(Interviewer.class, createModel.createChatLanguageModel());
        List<String> keyWords = interviewer.keyWord(topic);

        return Result.success(keyWords);
    }

    @Override
    public Result<List<String>> topicalAccordingToTheKeyWord(List<String> keyWord){
        Interviewer interviewer = AiServices.create(Interviewer.class, createModel.createChatLanguageModel());
        List<String> questions = interviewer.topics(keyWord);
        return Result.success(questions);
    }

    @Override
    public Result<String> startInterview(List<String> topics) {
        if (topics == null) {
            return Result.error("题目列表不能为空");
        }

        interviewTopics = new ArrayList<>(topics);
        currentTopicIndex = 0;
        return proceedToNextTopic();
    }

    private Result<String> proceedToNextTopic() {
        if (currentTopicIndex >= interviewTopics.size()) {
            return Result.success("所有题目已完成");
        }

        String currentTopic = interviewTopics.get(currentTopicIndex);
        try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
            String key = "qa_chatMemory : " + 1;
            String topicNoKey = "topicNo : ";
            Map<String, String> qaMap = new HashMap<>();
            Map<String, String> topicMap = new HashMap<>();
            qaMap.put(id + "、 AI : ", "你好，开始我们今天的面试，首先第一道题是 : " + currentTopic);
            topicMap.put(currentTopic + topicNo, "面试官 : 你好，开始我们今天的面试，首先第一道题是 : "  + currentTopic);
            id++;
            jedis.hset(key, qaMap);
            jedis.hset(topicNoKey, topicMap);
        }

        return Result.success("你好，开始我们今天的面试，首先第一道题是 : " + currentTopic);
    }

    @Override
    public Result<String> handleUserAnswer(String answer) {
        if (currentTopicIndex >= interviewTopics.size()) {
            return Result.error("面试已结束");
        }

        RedisChatMemoryStore redisChatMemoryStore = RedisChatMemoryStore.builder()
                .host("127.0.0.1")
                .port(6379)
                .build();

        ChatMemory chatMemory = MessageWindowChatMemory.builder()
                .maxMessages(50)
                .chatMemoryStore(redisChatMemoryStore)
                .build();

        RedisEmbeddingStore redisEmbeddingStore = RedisEmbeddingStore.builder()
                .port(6379)
                .host("127.0.0.1")
                .dimension(1537)
                .build();

        ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(redisEmbeddingStore)
                .embeddingModel(createModel.createEmbeddingModel())
                .minScore(0.9)
                .maxResults(5)
                .build();

        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .chatMemory(chatMemory)
                .contentRetriever(contentRetriever)
                .build();

        String currentTopic = interviewTopics.get(currentTopicIndex);
        Double finalScore = calculateAnswerSimilarity(currentTopic, answer).getData();
        try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
            topicNo++;
            String key = "qa_chatMemory : " + 1;
            String topicNoKey = "topicNo : ";
            Map<String, String> qaMap = new HashMap<>();
            Map<String, String> topicMap = new HashMap<>();
            qaMap.put(id + "、 USER : ", answer);
            topicMap.put(currentTopic + topicNo, "面试者 : " + answer);
            id++;
            jedis.hset(key, qaMap);
            jedis.hset(topicNoKey, topicMap);
        }

        if (finalScore > 0.9) {
            // 题目完成，执行过渡流程
            if (currentTopicIndex + 1 < interviewTopics.size()) {
                retry = 0;
                currentTopicIndex++;
                topicNo++;
                String nextTopic = interviewTopics.get(currentTopicIndex);
                String result =  interviewer.answerCorrectAndProceedNextTopic(currentTopic, nextTopic);
                try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                    String key = "qa_chatMemory : " + 1;
                    String topicNoKey = "topicNo : ";
                    Map<String, String> topicMap = new HashMap<>();
                    Map<String, String> qaMap = new HashMap<>();
                    qaMap.put(id + "、 AI : ", result);
                    topicMap.put(currentTopic + topicNo + " " + nextTopic + 1, "面试官 : " + result);
                    id++;
                    jedis.hset(key, qaMap);
                    jedis.hset(topicNoKey, topicMap);
                    topicNo = 1;
                }
                return Result.success(result);
            } else {
                currentTopicIndex++;
                topicNo++;
                try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                    String key = "qa_chatMemory : " + 1;
                    String topicNoKey = "topicNo : ";
                    Map<String, String> qaMap = new HashMap<>();
                    Map<String, String> topicMap = new HashMap<>();
                    qaMap.put(id + "、 AI : ", "感谢您的回答，面试全部题目已完成,感谢你的参与！");
                    topicMap.put(currentTopic + topicNo, "面试官 : 感谢您的回答，面试全部题目已完成,感谢你的参与！");
                    id++;
                    jedis.hset(key, qaMap);
                    jedis.hset(topicNoKey, topicMap);
                    topicNo++;
                }
                return Result.success("感谢您的回答，面试全部题目已完成,感谢你的参与！");
            }
        } else if (finalScore > 0.7 && finalScore < 0.9) {
            if(retry < 3){
                retry++;
                topicNo++;
                String standardAnswer = getStandardAnswer(currentTopic);
                String promptUser = interviewer.promptUser(currentTopic, answer, standardAnswer);
                try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                    String key = "qa_chatMemory : " + 1;
                    String topicNoKey = "topicNo : ";
                    Map<String, String> topicMap = new HashMap<>();
                    Map<String, String> qaMap = new HashMap<>();
                    qaMap.put(id + "、 AI : ", promptUser);
                    topicMap.put(currentTopic + topicNo, "面试官 : " + promptUser);
                    id++;
                    jedis.hset(key, qaMap);
                    jedis.hset(topicNoKey, topicMap);
                }
                return Result.success(promptUser);
            } else {
                currentTopicIndex++;
                topicNo++;
                if(currentTopicIndex < interviewTopics.size()){
                    retry = 0;
                    String nextTopic = interviewTopics.get(currentTopicIndex);
                    String result = interviewer.answerErrorAndProceedNextTopic(currentTopic, nextTopic);
                    try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                        String key = "qa_chatMemory : " + 1;
                        String topicNoKey = "topicNo : ";
                        Map<String, String> topicMap = new HashMap<>();
                        Map<String, String> qaMap = new HashMap<>();
                        qaMap.put(id + "、 AI : ", result);
                        topicMap.put(currentTopic + topicNo + " " + nextTopic + 1, "面试官 : " + result);
                        id++;
                        jedis.hset(key, qaMap);
                        jedis.hset(topicNoKey, topicMap);
                        topicNo = 1;
                    }
                    return Result.success(result);
                } else {
                    topicNo++;
                    try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                        String key = "qa_chatMemory : " + 1;
                        String topicNoKey = "topicNo : ";
                        Map<String, String> qaMap = new HashMap<>();
                        Map<String, String> topicMap = new HashMap<>();
                        qaMap.put(id + "、 AI : ", "感谢您的回答，面试全部题目已完成,感谢你的参与！");
                        topicMap.put(currentTopic + topicNo, "面试官 : 感谢您的回答，面试全部题目已完成,感谢你的参与！");
                        id++;
                        jedis.hset(key, qaMap);
                        jedis.hset(topicNoKey, topicMap);
                        topicNo = 1;
                    }
                    return Result.success("感谢您的回答，面试全部题目已完成,感谢你的参与！");
                }
            }
        } else {
            currentTopicIndex++;
            topicNo++;
            if(currentTopicIndex < interviewTopics.size()){
                retry = 0;
                String nextTopic = interviewTopics.get(currentTopicIndex);
                String result = interviewer.answerErrorAndProceedNextTopic(currentTopic, nextTopic);
                try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                    String key = "qa_chatMemory : " + 1;
                    String topicNoKey = "topicNo : ";
                    Map<String, String> topicMap = new HashMap<>();
                    Map<String, String> qaMap = new HashMap<>();
                    qaMap.put(id + "、 AI : ", result);
                    topicMap.put(currentTopic + topicNo + " " + nextTopic + 1, "面试官 : " + result);
                    id++;
                    jedis.hset(key, qaMap);
                    jedis.hset(topicNoKey, topicMap);
                    topicNo = 1;
                }
                return Result.success(result);
            } else {
                topicNo++;
                try(Jedis jedis = new Jedis("127.0.0.1", 6379)){
                    String key = "qa_chatMemory : " + 1;
                    String topicNoKey = "topicNo : ";
                    Map<String, String> qaMap = new HashMap<>();
                    Map<String, String> topicMap = new HashMap<>();
                    qaMap.put(id + "、 AI : ", "感谢您的回答，面试全部题目已完成,感谢你的参与！");
                    topicMap.put(currentTopic + topicNo, "面试官 : 感谢您的回答，面试全部题目已完成,感谢你的参与！");
                    id++;
                    jedis.hset(key, qaMap);
                    jedis.hset(topicNoKey, topicMap);
                    topicNo = 1;
                }
                return Result.success("感谢您的回答，面试全部题目已完成,感谢你的参与！");
            }
        }
    }

    @Override
    public Result<String> interview(InterviewRequest interviewRequest){
        RedisChatMemoryStore redisChatMemoryStore = RedisChatMemoryStore.builder()
                .host("127.0.0.1")
                .port(6379)
                .build();

        RedisEmbeddingStore redisEmbeddingStore = RedisEmbeddingStore.builder()
                .port(6379)
                .host("127.0.0.1")
                .dimension(1537)
                .build();

        ChatMemory chatMemory = MessageWindowChatMemory.builder()
                .maxMessages(50)
                .chatMemoryStore(redisChatMemoryStore)
                .build();

        ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(redisEmbeddingStore)
                .embeddingModel(createModel.createEmbeddingModel())
                .minScore(0.9)
                .maxResults(5)
                .build();

        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .chatMemory(chatMemory)
                .contentRetriever(contentRetriever)
                .build();

        String aiMessage = interviewer.interview(interviewRequest.getTopics(), interviewRequest.getAnswer());
        return Result.success(aiMessage);
    }

    @Override
    public Result<Map<String, List<String>>> searchAnswer(List<String> questionList){

        WebSearchEngine webSearchEngine = TavilyWebSearchEngine.builder()
                .apiKey("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") // get a free key: https://app.tavily.com/sign-in
                .build();

        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .build();

        ContentRetriever webSearchContentRetriever = WebSearchContentRetriever.builder()
                .webSearchEngine(webSearchEngine)
                .maxResults(5)
                .build();

        List<String> strList = new ArrayList<>();
        Map<String, List<String>> returnMap = new HashMap<>();
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        for (String question : questionList){
            Map<String, List<String>> map = new HashMap<>();
            List<Content> contents = webSearchContentRetriever.retrieve(new Query(question));
            for (Content content : contents) {
                strList.add(interviewer.wash(content));
            }
            returnMap.put(question, strList);
            map.put(question, strList);
            redisService.saveMap(question, map);
        }

        return Result.success(returnMap);
    }

    @Override
    public Result<String> storeAndEmbeddingAnswerAndQuestion(List<String> questionList){

        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .build();
        RedisEmbeddingStore embeddingStore = RedisEmbeddingStore.builder()
                .host("127.0.0.1")
                .port(6379)
                .dimension(1536)
                .build();

        for (String question : questionList){
            TextSegment questionText = new Content(question).textSegment();
            TextSegment answer = interviewer.getAnswer(question);
            embeddingStore.add(createModel.createEmbeddingModel().embed(answer).content(), questionText);
        }


        return Result.success("success");
    }

    @Override
    public Result<String> summarizeInterview(){
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)){
            Interviewer interviewer = AiServices.builder(Interviewer.class)
                    .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                    .chatLanguageModel(createModel.createChatLanguageModel())
                    .build();
            List<String> chatMemory = new ArrayList<>();
            System.out.println(id);
            for(int i = 1; i < id; i++){
                if(i % 2 == 1){
                    chatMemory.add("AI : " + jedis.hget("qa_chatMemory : 1", i + "、 AI : "));
                }
                else {
                    chatMemory.add("USER : " + jedis.hget("qa_chatMemory : 1", i + "、 USER : "));
                }
            }
            List<String> summarizeAboutChatMemorys = interviewer.summarizeAboutChatMemory(chatMemory);
            List<String> summarizeChatMemoryReturnTopics = interviewer.summarizeChatMemoryReturnTopics(chatMemory);
            List<Map<String, String>> knowledgePointList = new ArrayList<>();

            System.out.println(summarizeAboutChatMemorys);
            System.out.println(summarizeChatMemoryReturnTopics);

            List<KnowledgeLevel> knowledgeLevelList = knowledgeLevelMapper.selectList(new QueryWrapper<>());
            for(KnowledgeLevel knowledgeLevel : knowledgeLevelList){
                Map<String, String> knowledgePoint = new HashMap<>();
                knowledgePoint.put("levelOne", knowledgeLevel.getLevelOne());
                knowledgePoint.put("levelTwo", knowledgeLevel.getLevelTwo());
                knowledgePoint.put("levelThree", knowledgeLevel.getLevelThree());

                knowledgePointList.add(knowledgePoint);
            }

            ErrorSet errorSet = new ErrorSet();
            int i = 0;
            for(String summarizeChatMemoryReturnTopic : summarizeChatMemoryReturnTopics){
                if(summarizeChatMemoryReturnTopic.isEmpty())
                    continue;
                Iterator<String> iterator = summarizeAboutChatMemorys.iterator();
                while (iterator.hasNext()) {
                    String item = iterator.next();
                    if (item.isEmpty()) {
                        iterator.remove();
                    }
                }
                String summarizeTopicsStr = interviewer.summarizeTopics(summarizeChatMemoryReturnTopic, knowledgePointList);
                Gson gson = new Gson();
                Type mapType = new TypeToken<Map<String, String>>(){}.getType();
                Map<String, String> knowledgePointList_new = gson.fromJson(summarizeTopicsStr, mapType);
                String levelThree = knowledgePointList_new.get("levelThree");

                // 检查是否存在该知识点
                List<KnowledgeLevel> existing = knowledgeLevelMapper.selectList(
                        new QueryWrapper<KnowledgeLevel>().eq("level_three", levelThree)
                );
                int knowledgeId;
                if(existing.isEmpty()){
                    KnowledgeLevel knowledgeLevel = new KnowledgeLevel();
                    knowledgeLevel.setLevelOne(knowledgePointList_new.get("levelOne"));
                    knowledgeLevel.setLevelTwo(knowledgePointList_new.get("levelTwo"));
                    knowledgeLevel.setLevelThree(knowledgePointList_new.get("levelThree"));
                    knowledgeLevelMapper.insert(knowledgeLevel);
                    knowledgeId = knowledgeLevel.getId();
                } else {
                    // 已存在则取已有ID
                    knowledgeId = existing.get(0).getId();
                }
                System.out.println(knowledgePointList_new);
                errorSet.setUserId(summarizeChatMemoryReturnTopic);
                errorSet.setTopic(summarizeChatMemoryReturnTopic);
                errorSet.setAnswerParsing(summarizeAboutChatMemorys.get(i));
                errorSet.setKnowledgeNo(knowledgeId);
                errorSet.setStatus(1);
                i++;
                errorSetMapper.insert(errorSet);
            }
            return Result.success();
        }
    }

    @Override
    public Result<List<String>> readWeakKnowledgePointsAndAnalyze(User user){
        String userId = user.getUserId();
        List<ErrorSet> errorBook = errorSetMapper.selectList(new QueryWrapper<ErrorSet>().eq("user_id", userId));
        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .chatLanguageModel(createModel.createChatLanguageModel())
                .build();
        List<String> topics = new ArrayList<>();
        for(ErrorSet errorSet : errorBook){
            topics.add(errorSet.getTopic());
        }
        return Result.success(interviewer.ExtractKeywordsAccordingToErrorBook(topics));

    }

    @Override
    public Result<String> generateAndStoreStandardAnswers(SearchAnswerRequest questions) {
        // 使用Jedis代替RedisTemplate，避免配置问题
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            // 创建知识库向量存储（用于检索知识）
            RedisEmbeddingStore knowledgeEmbeddingStore = RedisEmbeddingStore.builder()
                    .host("127.0.0.1")
                .port(6379)
                    .dimension(1536)
                    .indexName("knowledge_index") // 使用特定索引名称
                    .build();

            // 创建答案向量存储（用于存储生成的答案）
            RedisEmbeddingStore answerEmbeddingStore = RedisEmbeddingStore.builder()
                .host("127.0.0.1")
                    .port(6379)
                    .dimension(1536)
                    .indexName("answer_index") // 使用特定索引名称
                    .build();

            // 创建内容检索器，用于从知识库检索
            ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                    .embeddingStore(knowledgeEmbeddingStore) // 使用知识库向量存储
                    .embeddingModel(createModel.createEmbeddingModel())
                    .minScore(0.7)
                    .maxResults(3)
                    .build();

            // 创建AI服务，配置了contentRetriever后会自动执行RAG
            Interviewer interviewer = AiServices.builder(Interviewer.class)
                    .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                    .chatLanguageModel(createModel.createChatLanguageModel())
                    .contentRetriever(contentRetriever)
                    .build();

            // 为每个问题生成标准答案
            for (String question : questions.getQuestions()) {
                try {
                    // 手动查询相关知识点并在控制台输出
                    System.out.println("\n========== 问题: " + question + " ==========");
                    // 将问题转换为向量
                    TextSegment questionText = new Content(question).textSegment();
                    var questionEmbedding = createModel.createEmbeddingModel().embed(questionText).content();

                    // 在知识库向量存储中查找相关内容
                    List<EmbeddingMatch<TextSegment>> relevantSegments = knowledgeEmbeddingStore.findRelevant(questionEmbedding, 3);

                    // 在控制台输出相关知识点
                    if (relevantSegments.isEmpty()) {
                        System.out.println("未找到相关知识点，将使用模型自行生成答案");
                    } else {
                        System.out.println("找到相关知识点:");
                        for (int i = 0; i < relevantSegments.size(); i++) {
                            TextSegment segment = relevantSegments.get(i).embedded();
                            System.out.println(segment);
                        }
                    }

                    // 直接调用getAnswer，LangChain4j会自动执行RAG流程
                    String standardAnswer = interviewer.getAnswer(question).text();

                    // 使用Jedis直接存储问题和答案
                    String key = "interview:qa:" + question;

                    Embedding answerEmbedding = createModel.createEmbeddingModel().embed(standardAnswer).content();
                    float[] vectorData = answerEmbedding.vector();
                    StringBuilder vectorString = new StringBuilder("[");
                    for (int i = 0; i < vectorData.length; i++) {
                        if (i > 0) vectorString.append(",");
                        vectorString.append(vectorData[i]);
                    }
                    vectorString.append("]");

                    // 存储为哈希表
                    Map<String, String> qaMap = new HashMap<>();
                    qaMap.put("question", question);
                    qaMap.put("answer", standardAnswer);
                    qaMap.put("embedding_vector", vectorString.toString());
                    jedis.hset(key, qaMap);
                    System.out.println("成功存储QA对: " + question);


                    // 将答案向量化并存储到答案向量存储中
//                    TextSegment answerText = new Content(standardAnswer).textSegment();
//                    answerEmbeddingStore.add(createModel.createEmbeddingModel().embed(answerText).content(), questionText);
//                    System.out.println("成功向量化答案并存储到答案索引中");

                } catch (Exception e) {
                    e.printStackTrace();
                    return Result.error("生成答案时发生错误：" + e.getMessage());
                }
            }

            return Result.success("标准答案生成并存储成功，共处理 " + questions.getQuestions().size() + " 个问题");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("Redis连接错误：" + e.getMessage());
        }
    }

    private boolean isVagueAnswer(String answer) {
        if (answer == null) return true;
        String trimmed = answer.trim();
        // 如果答案长度非常短或包含常见的模糊表达，则认为答案模糊
        return trimmed.length() < 5 || trimmed.contains("不太清楚") || trimmed.contains("不知道");
    }


    @Override
    public Result<Double> calculateAnswerSimilarity(String question, String userAnswer) {
        try {
            // 获取标准答案
            String vectorStr = getStandardAnswerEmbedding(question);
            String standardAnswer = getStandardAnswer(question);
            if (vectorStr == null || standardAnswer == null) {
                return Result.error("无法获取标准答案或嵌入向量");
            }
            
            vectorStr = vectorStr.replace("[", "").replace("]", "");
            String[] values = vectorStr.split(",");
            float[] vector = new float[values.length];
            for (int i = 0; i < values.length; i++) {
                vector[i] = Float.parseFloat(values[i].trim());
            }
            Embedding embeddingStandardAnswer = Embedding.from(vector);

            // 计算动态权重
            Map<String, Double> weights = calculateDynamicWeights(standardAnswer, userAnswer);

            // 创建线程池
            ExecutorService executor = Executors.newFixedThreadPool(4);
            
            // 提交各维度计算任务
            Future<Double> semanticFuture = executor.submit(() -> {
                System.out.println(1);
                double score = calculateSemanticSimilarity(embeddingStandardAnswer, userAnswer);

                return calibrateScore(score, "semantic");
            });
            
            Future<Double> keywordFuture = executor.submit(() -> {
                System.out.println(2);
                double score = calculateKeywordCoverage(standardAnswer, userAnswer);

                return calibrateScore(score, "keyword");
            });
            
            Future<Double> completenessFuture = executor.submit(() -> {
                System.out.println(3);
                double score = calculateAnswerCompleteness(standardAnswer, userAnswer);

                return calibrateScore(score, "completeness");
            });
            
            Future<Double> structureFuture = executor.submit(() -> {
                System.out.println(4);
                double score = calculateStructureSimilarity(standardAnswer, userAnswer);

                return calibrateScore(score, "structure");
            });
            
            // 获取各维度评分结果
            double semanticSimilarity = semanticFuture.get();
            double keywordCoverage = keywordFuture.get();
            double completeness = completenessFuture.get();
            double structureSimilarity = structureFuture.get();
            
            // 关闭线程池
            executor.shutdown();

            // 计算最终得分
            double finalScore = calculateFinalScore(
                semanticSimilarity, keywordCoverage, completeness, structureSimilarity, weights
            );

            // 记录评分日志
            logScoreDetails(question, semanticSimilarity, keywordCoverage, completeness,
                          structureSimilarity, finalScore, weights);

            return Result.success(finalScore);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("计算相似度时发生错误：" + e.getMessage());
        }
    }

    @Override
    public Result<List<String>> summarizeResume(String filePath) throws IOException {
        String resume;
        if (filePath.toLowerCase().endsWith(".pdf")) {
            resume = pdfToString.pdfToString(filePath);
        } else {
            resume = Files.readString(Paths.get(filePath));
        }
        System.out.println(resume);

        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .build();
        return Result.success(interviewer.summarizeResume(resume));
    }

    /**
     * 计算动态权重
     */
    private Map<String, Double> calculateDynamicWeights(String standardAnswer, String userAnswer) {
        Map<String, Double> weights = new HashMap<>();

        // 计算答案长度比例
        double lengthRatio = (double) userAnswer.length() / standardAnswer.length();
        lengthRatio = Math.min(1.0, Math.max(0.0, lengthRatio));

        // 计算答案复杂度（基于关键词数量）
        Interviewer interviewer = AiServices.create(Interviewer.class, createModel.createChatLanguageModel());
        List<String> standardKeywords = Collections.singletonList(interviewer.getKeyWords(Collections.singletonList(standardAnswer).toString()));
        List<String> userKeywords = Collections.singletonList(interviewer.getKeyWords(Collections.singletonList(userAnswer).toString()));
        double complexityRatio = (double) userKeywords.size() / standardKeywords.size();
        complexityRatio = Math.min(1.0, Math.max(0.0, complexityRatio));

        // 根据长度和复杂度调整权重
        double lengthFactor = 1.0 + (lengthRatio - 0.5) * LENGTH_WEIGHT_FACTOR;
        double complexityFactor = 1.0 + (complexityRatio - 0.5) * COMPLEXITY_WEIGHT_FACTOR;

        // 计算长度补偿因子
        double lengthCompensation = 1.0 - Math.abs(lengthRatio - 1.0) * 0.2;

        // 计算最终权重
        weights.put("semantic", BASE_SEMANTIC_WEIGHT * lengthFactor);
        weights.put("keyword", BASE_KEYWORD_WEIGHT * complexityFactor);
        weights.put("completeness", BASE_COMPLETENESS_WEIGHT * lengthCompensation);
        weights.put("structure", BASE_STRUCTURE_WEIGHT);

        // 归一化权重
        double totalWeight = weights.values().stream().mapToDouble(Double::doubleValue).sum();
        weights.replaceAll((k, v) -> v / totalWeight);

        return weights;
    }

    /**
     * 评分校准
     */
    private double calibrateScore(double rawScore, String dimension) {
        // 应用非线性变换
        double calibratedScore = Math.pow(rawScore, 1.2);

        // 根据维度特性调整
        switch (dimension) {
            case "semantic":
                calibratedScore = applySemanticCalibration(calibratedScore);
                break;
            case "keyword":
                calibratedScore = applyKeywordCalibration(calibratedScore);
                break;
            case "completeness":
                calibratedScore = applyCompletenessCalibration(calibratedScore);
                break;
            case "structure":
                calibratedScore = applyStructureCalibration(calibratedScore);
                break;
        }

        return normalizeScore(calibratedScore);
    }

    /**
     * 计算最终得分
     */
    private double calculateFinalScore(
            double semanticSimilarity, double keywordCoverage,
            double completeness, double structureSimilarity,
            Map<String, Double> weights) {

        return semanticSimilarity * weights.get("semantic") +
               keywordCoverage * weights.get("keyword") +
               completeness * weights.get("completeness") +
               structureSimilarity * weights.get("structure");
    }

    /**
     * 记录评分详情
     */
    private void logScoreDetails(String question, double semanticSimilarity,
                               double keywordCoverage, double completeness,
                               double structureSimilarity, double finalScore,
                               Map<String, Double> weights) {
        // 记录评分日志
        System.out.println("问题: " + question);
        System.out.println("语义相似度: " + semanticSimilarity + " (权重: " + weights.get("semantic") + ")");
        System.out.println("关键词覆盖度: " + keywordCoverage + " (权重: " + weights.get("keyword") + ")");
        System.out.println("完整性: " + completeness + " (权重: " + weights.get("completeness") + ")");
        System.out.println("结构相似度: " + structureSimilarity + " (权重: " + weights.get("structure") + ")");
        System.out.println("最终得分: " + finalScore);
    }

    /**
     * 从Redis中获取标准答案的Embedding向量字符串
     *
     * @param question 问题
     * @return Embedding向量字符串，如果不存在则返回null
     */
    private String getStandardAnswerEmbedding(String question) {
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            // 构建Redis键
            String key = "interview:qa:" + question;

            // 检查键是否存在
            if (!jedis.exists(key)) {
                return null;
            }

            // 直接从哈希表中获取embedding_vector字段
            return jedis.hget(key, "embedding_vector");
        } catch (Exception e) {
            System.err.println("从Redis获取Embedding向量失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 获取标准答案
     */
    private String getStandardAnswer(String question) {
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            // 构建Redis键
            String key = "interview:qa:" + question;

            // 检查键是否存在
            if (!jedis.exists(key)) {
                return null;
            }

            // 直接从哈希表中获取answer字段
            return jedis.hget(key, "answer");
        } catch (Exception e) {
            System.err.println("从Redis获取Embedding向量失败: " + e.getMessage());
            return null;
        }
    }

    // 各维度的校准方法
    private double applySemanticCalibration(double score) {
        // 语义相似度校准：增强高分段区分度
        return score > 0.8 ? 0.8 + (score - 0.8) * 1.5 : score;
    }

    private double applyKeywordCalibration(double score) {
        // 关键词覆盖度校准：平滑处理
        return score > 0.6 ? 0.6 + (score - 0.6) * 0.8 : score;
    }

    private double applyCompletenessCalibration(double score) {
        // 完整性校准：线性调整
        return score * 0.9 + 0.1;
    }

    private double applyStructureCalibration(double score) {
        // 改为连续函数调整
        return score * 0.9 + 0.1;
    }

    /**
     * 计算语义相似度
     */
    private double calculateSemanticSimilarity(Embedding embeddingStandardAnswer, String userAnswer) {
        if (isVagueAnswer(userAnswer)) {
            return 0.1;
        }
        TextSegment userAnswerText = new Content(userAnswer).textSegment();
        Embedding userAnswerEmbedding = createModel.createEmbeddingModel().embed(userAnswerText).content();
        return cosineSimilarity(embeddingStandardAnswer.vector(), userAnswerEmbedding.vector());
    }

    /**
     * 计算关键词覆盖度
     */
    private double calculateKeywordCoverage(String standardAnswer, String userAnswer) {

        if (isVagueAnswer(userAnswer)) {
            return 0.1;
        }
        try {
            // 使用AI提取标准答案和用户答案中的关键词
            Interviewer interviewer = AiServices.create(Interviewer.class, createModel.createChatLanguageModel());
            List<String> standardKeywords = Collections.singletonList(interviewer.getKeyWords(Collections.singletonList(standardAnswer).toString()));
            List<String> userKeywords = Collections.singletonList(interviewer.getKeyWords(Collections.singletonList(userAnswer).toString()));

            if (standardKeywords.isEmpty() || userKeywords.isEmpty()) {
                return 0.0;
            }
            System.out.println(standardKeywords);
            System.out.println(userKeywords);
            // 创建向量模型
            OpenAiEmbeddingModel embeddingModel = createModel.createEmbeddingModel();

            // 计算标准答案关键词的向量
            List<float[]> standardKeywordVectors = new ArrayList<>();
            for (String keyword : standardKeywords) {
                TextSegment keywordText = new Content(keyword).textSegment();
                standardKeywordVectors.add(embeddingModel.embed(keywordText).content().vector());
            }

            // 计算用户答案关键词的向量
            List<float[]> userKeywordVectors = new ArrayList<>();
            for (String keyword : userKeywords) {
                TextSegment keywordText = new Content(keyword).textSegment();
                userKeywordVectors.add(embeddingModel.embed(keywordText).content().vector());
            }

            // 计算每个标准关键词与用户关键词的相似度
            double totalSimilarity = 0.0;
            for (float[] standardVector : standardKeywordVectors) {
                double maxSimilarity = 0.0;
                for (float[] userVector : userKeywordVectors) {
                    double similarity = cosineSimilarity(standardVector, userVector);
                    maxSimilarity = Math.max(maxSimilarity, similarity);
                }

                // 如果最大相似度超过阈值，认为匹配成功
                if (maxSimilarity > KEYWORD_HIGH_THRESHOLD) {
                    totalSimilarity += 0.8;
                } else if (maxSimilarity > KEYWORD_MEDIUM_THRESHOLD) {
                    // 相似度在0.5-0.7之间，给予部分分数
                    totalSimilarity += 0.4;
                }
            }

            return totalSimilarity / standardKeywords.size();
        } catch (Exception e) {
            e.printStackTrace();
            return 0.5; // 发生错误时返回默认值
        }
    }

    /**
     * 计算答案完整性
     */
    private double calculateAnswerCompleteness(String standardAnswer, String userAnswer) {

        if (isVagueAnswer(userAnswer)) {
            return 0.1;
        }
        // 使用AI评估答案的完整性
        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .build();

        String result = interviewer.completeness(standardAnswer, userAnswer);

        try {
            return Double.parseDouble(result);
        } catch (NumberFormatException e) {
            return 0.5; // 默认值
        }
    }

    /**
     * 计算答案结构相似度
     */
    private double calculateStructureSimilarity(String standardAnswer, String userAnswer) {

        if (isVagueAnswer(userAnswer)) {
            return 0.1;
        }
        // 使用AI评估答案的结构相似度
        Interviewer interviewer = AiServices.builder(Interviewer.class)
                .streamingChatLanguageModel(createModel.createStreamingChatLanguageModel())
                .chatLanguageModel(createModel.createChatLanguageModel())
                .build();
        String result = interviewer.constructSimilarity(standardAnswer, userAnswer);

        try {
            return Double.parseDouble(result);
        } catch (NumberFormatException e) {
            return 0.5; // 默认值
        }
    }

    /**
     * 计算两个向量的余弦相似度
     */
    private double cosineSimilarity(float[] vector1, float[] vector2) {
        if (vector1.length != vector2.length) {
            throw new IllegalArgumentException("向量维度不匹配");
        }

        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;

        for (int i = 0; i < vector1.length; i++) {
            dotProduct += vector1[i] * vector2[i];
            norm1 += vector1[i] * vector1[i];
            norm2 += vector2[i] * vector2[i];
        }

        norm1 = Math.sqrt(norm1);
        norm2 = Math.sqrt(norm2);

        if (norm1 == 0.0 || norm2 == 0.0) {
            return 0.0;
        }

        return dotProduct / (norm1 * norm2);
    }

    // 统一评分规则
    private double normalizeScore(double rawScore) {
        return Math.max(0.0, Math.min(1.0, rawScore)); // 确保0-1范围
    }

    // 关键词评分曲线优化
    private double applyKeywordScaling(double rawScore) {
        return Math.pow(rawScore, 1.5); // 非线性转换增强高分段区分度
    }

    // AI评分校验
    private double validateAIOutput(String aiResponse) {
        try {
            double score = Double.parseDouble(aiResponse);
            return normalizeScore(score);
        } catch (NumberFormatException e) {
            return 0.5; // 默认值需记录日志
        }
    }

    // 所有评分最终转换为0-1连续值
    private static double convertToContinuous(double keywordScore) {
        // 原离散评分：0.0, 0.5, 1.0 → 转换为0.0, 0.7, 1.0
        return keywordScore < 0.5 ? 0.0 :
               keywordScore < 1.0 ? 0.7 : 1.0;
    }
}